import {
    ExceptionFilter,
    Catch,
    ArgumentsHost,
    HttpException,
    HttpStatus,
    Injectable,
} from '@nestjs/common';
import { Response } from 'express';
import { AppI18nService } from '../../i18n/i18n.service';
import { ApiResponseDto } from '../dto/api-response.dto';

@Injectable()
@Catch(HttpException)
export class I18nExceptionFilter implements ExceptionFilter {
    constructor(private readonly i18nService: AppI18nService) { }

    async catch(exception: HttpException, host: ArgumentsHost) {
        const ctx = host.switchToHttp();
        const response = ctx.getResponse<Response>();
        const request = ctx.getRequest();
        const status = exception.getStatus();

        // 获取语言设置，优先从请求头，然后是查询参数，最后是默认语言
        const language = request.headers['accept-language'] ||
            request.query.lang ||
            'en';

        let message: string;
        const exceptionResponse = exception.getResponse();

        // 处理不同类型的异常响应
        if (typeof exceptionResponse === 'string') {
            // 简单字符串响应
            message = this.getI18nMessage(exceptionResponse, language);
        } else if (typeof exceptionResponse === 'object' && exceptionResponse !== null) {
            // 对象响应
            const responseObj = exceptionResponse as any;
            if (responseObj.message) {
                if (Array.isArray(responseObj.message)) {
                    // 验证错误数组
                    message = responseObj.message.map((msg: string) =>
                        this.getI18nMessage(msg, language)
                    ).join(', ');
                } else {
                    message = this.getI18nMessage(responseObj.message, language);
                }
            } else {
                message = this.getI18nMessage(exception.message, language);
            }
        } else {
            message = this.getI18nMessage(exception.message, language);
        }

        // 创建标准化的错误响应
        const errorResponse = ApiResponseDto.error(null, message);

        response.status(status).json(errorResponse);
    }

    private getI18nMessage(messageKey: string, language: string): string {
        // 尝试将常见的错误消息映射到i18n键
        const messageMap: Record<string, string> = {
            'User not found': 'user.not_found',
            'Invalid signature': 'auth.invalid_signature',
            'Unauthorized': 'auth.unauthorized',
            'Bad Request': 'api.bad_request',
            'Forbidden': 'api.forbidden',
            'Not Found': 'api.not_found',
            'Internal Server Error': 'api.internal_error',
        };

        // 如果消息已经是i18n键格式，直接使用
        if (messageKey.includes('.')) {
            try {
                return this.i18nService.translate(messageKey, {}, language);
            } catch (error) {
                return messageKey; // 如果翻译失败，返回原始消息
            }
        }

        // 尝试映射常见错误消息
        const i18nKey = messageMap[messageKey];
        if (i18nKey) {
            try {
                return this.i18nService.translate(i18nKey, {}, language);
            } catch (error) {
                return messageKey; // 如果翻译失败，返回原始消息
            }
        }

        // 如果无法映射，返回原始消息
        return messageKey;
    }
}
